// SPDX-License-Identifier: Mulan PSL v2
/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * This software is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

mod config;
mod core;
mod dispatcher;
mod error;
mod gpu;
mod handlers;
mod mock_common; // Temporary mock for xgpu-common

use crate::config::ServerConfig;
use crate::core::XGPUServer;
use crate::error::ServerResult;

#[tokio::main]
async fn main() -> ServerResult<()> {
    // Initialize logging
    init_logging();
    
    log::info!("Starting xgpu-server...");
    
    // Create server from environment configuration
    let mut server = XGPUServer::from_env()?;
    
    // Set up signal handling for graceful shutdown
    let shutdown_handle = setup_signal_handlers();
    
    // Start the server
    tokio::select! {
        result = server.start() => {
            match result {
                Ok(()) => log::info!("Server started successfully"),
                Err(e) => {
                    log::error!("Failed to start server: {}", e);
                    return Err(e);
                }
            }
        }
        _ = shutdown_handle => {
            log::info!("Shutdown signal received, stopping server...");
            server.stop().await?;
        }
    }
    
    log::info!("xgpu-server shutdown complete");
    Ok(())
}

/// Initialize logging based on environment variables or default settings.
fn init_logging() {
    let log_level = std::env::var("XGPU_LOG_LEVEL")
        .unwrap_or_else(|_| "info".to_string());
    
    let mut builder = env_logger::Builder::new();
    
    // Set log level
    if let Ok(level) = log_level.parse::<log::LevelFilter>() {
        builder.filter_level(level);
    } else {
        builder.filter_level(log::LevelFilter::Info);
    }
    
    // Set custom format
    builder.format(|buf, record| {
        use std::io::Write;
        writeln!(
            buf,
            "[{}] [{}] [{}:{}] {}",
            chrono::Utc::now().format("%Y-%m-%d %H:%M:%S%.3f UTC"),
            record.level(),
            record.file().unwrap_or("unknown"),
            record.line().unwrap_or(0),
            record.args()
        )
    });
    
    builder.init();
    
    log::info!("Logging initialized with level: {}", log_level);
}

/// Set up signal handlers for graceful shutdown.
async fn setup_signal_handlers() {
    use tokio::signal;
    
    #[cfg(unix)]
    {
        let mut sigterm = signal::unix::signal(signal::unix::SignalKind::terminate())
            .expect("Failed to register SIGTERM handler");
        let mut sigint = signal::unix::signal(signal::unix::SignalKind::interrupt())
            .expect("Failed to register SIGINT handler");
        
        tokio::select! {
            _ = sigterm.recv() => log::info!("Received SIGTERM"),
            _ = sigint.recv() => log::info!("Received SIGINT"),
        }
    }
    
    #[cfg(windows)]
    {
        let _ = signal::ctrl_c().await;
        log::info!("Received Ctrl+C");
    }
}
